/**
 * This file is released under the GNU General Public License.
 * Refer to the COPYING file distributed with this package.
 *
 * Copyright (c) 2008-2009 WURFL-Pro srl
 */
package net.sourceforge.wurfl.core;

import java.io.File;

import net.sourceforge.wurfl.core.handlers.matchers.MatcherManager;
import net.sourceforge.wurfl.core.resource.DefaultWURFLModel;
import net.sourceforge.wurfl.core.resource.WURFLModel;
import net.sourceforge.wurfl.core.resource.WURFLResource;
import net.sourceforge.wurfl.core.resource.WURFLResources;
import net.sourceforge.wurfl.core.resource.XMLResource;

import org.apache.commons.lang.Validate;

/**
 * Custom WURFLHolder implementation.
 * <p>
 * It permits to initialize WURFLHolder by path, File or WURFLResource.
 * </p>
 * 
 * @author WURFL-PRO SRL, Rome, Italy
 * @version $Id: CustomWURFLHolder.java 1045 2009-03-09 15:52:53Z filippo.deluca $
 */
public class CustomWURFLHolder implements WURFLHolder {

	/** Root WURFLResource */
	private WURFLResource root;

	/** Patches WURFLResources */
	private WURFLResources patches;

	/** Delegate WURFLHolder */
	private WURFLHolder delegate;

	// Constructors *******************************************************

	public CustomWURFLHolder(WURFLResource root, WURFLResources patches) {

		Validate.notNull(root, "The root resource is null");
		// XXX validate patches too?

		this.root = root;
		this.patches = patches;

		init();
	}

	public CustomWURFLHolder(WURFLResource root) {

		this(root, new WURFLResources());
	}

	public CustomWURFLHolder(String rootPath, String[] patchesPath) {

		Validate.notEmpty(rootPath, "The rootPath is null");

		root = new XMLResource(rootPath);

		patches = new WURFLResources();
		for (int index = 0; patchesPath != null && index < patchesPath.length; index++) {
			patches.add(new XMLResource(patchesPath[index]));
		}

		init();
	}

	public CustomWURFLHolder(String rootPath) {

		this(rootPath, new String[] {});
	}

	public CustomWURFLHolder(File rootFile, File[] patchesFile) {

		Validate.notNull(rootFile, "The rootFile is null");
		Validate.isTrue(rootFile.exists(), "The rootFile does not exist");
		Validate.isTrue(rootFile.canRead(), "The rootFile is not readable");

		root = new XMLResource(rootFile);

		patches = new WURFLResources();
		for (int index = 0; patchesFile != null && index < patchesFile.length; index++) {

			Validate.notNull(patchesFile[index], "The pathFile is null");
			Validate.isTrue(patchesFile[index].exists(),
					"The pathFile does not exist");
			Validate.isTrue(patchesFile[index].canRead(),
					"The patchFile is not readable");

			patches.add(new XMLResource(patchesFile[index]));
		}

		init();
	}

	public CustomWURFLHolder(File rootFile) {

		this(rootFile, new File[] {});
	}

	/**
	 * This method build the WURFLManager instance using default implementations
	 * of all required interfaces.
	 * 
	 * @return a WURFLManager instance.
	 */
	protected void init() {

		WURFLModel model = new DefaultWURFLModel(root, patches);

		MatcherManager matcherManager = new MatcherManager(model);

		DeviceProvider deviceProvider = new DefaultDeviceProvider(model);

		WURFLService service = new DefaultWURFLService(matcherManager,
				deviceProvider);

		WURFLManager manager = new DefaultWURFLManager(service);

		WURFLUtils utils = new WURFLUtils(model, deviceProvider);

		createDelegate(manager, utils);
	}
	
	/**
	 * Create WURFLHolder delegate from WURFLManager and URFLUtils.
	 * 
	 * @param manager
	 *            The WURFLManager associated with delegate.
	 * @param utils
	 *            The WURFLUtils associated with delegate.
	 */
	protected void createDelegate(WURFLManager manager, WURFLUtils utils) {
		delegate = new DefaultWURFLHolder(manager, utils);
	}

	// Delegate methods ***************************************************

	public WURFLManager getWURFLManager() {
		return delegate.getWURFLManager();
	}

	public WURFLUtils getWURFLUtils() {
		return delegate.getWURFLUtils();
	}


}
